#define DEBUG
#include <cstdio>
#define MAXN 100000
#define MAXM 100000
#define MAXQ 100000

using namespace std;

int min(int a, int b) {
  return a<b ? a : b;
}

int max(int a, int b) {
  return a>b ? a : b;
}

class Graph {
public:
  int m, ind[MAXN+1], to[MAXN*2-1], link[MAXN*2-1], dep[MAXN+1], dfn[MAXN+1], size[MAXN+1];

  void addSide(int u, int v) {
    m++;
    to[m] = v;
    link[m] = ind[u];
    ind[u] = m;
  }

  void build(int o, int fa) {
    size[o] = 1;
    dfn[o] = ++dfn[0];
    dep[o] = dep[fa]+1;
    for (int i=ind[o]; i; i=link[i]) {
      if (to[i]!=fa) {
	build(to[i], o);
	size[o] += size[to[i]];
      }
    }
  }
};

class SegmentTree {
public:
  SegmentTree *left, *right;
  int l, r, w;

  SegmentTree(int l, int r) {
    left=right=NULL;
    this->l = l, this->r = r;
    w=0;
  }

  void add(int t, int v) {
    if (l==r) {
      w += v;
    } else {
      int mid=(l+r)/2;
      if (t<=mid) {
	if (!left) {
	  left = new SegmentTree(l, mid);
	}
	left->add(t, v);
      } else {
	if (!right) {
	  right = new SegmentTree(mid+1, r);
	}
	right->add(t, v);
      }
    }
  }

  int get(int tl, int tr) {
    if (l==tl && r==tr) {
      return w;
    } else {
      int mid=(l+r)/2, ret=0;
      if (tr>=l && tl<=mid && left) {
	ret += left->get(max(l, tl), min(mid, tr));
      }
      if (tr>mid && tl<=r && right) {
	ret += right->get(max(mid+1, tl), min(r, tr));
      }
      return ret;
    }
  }
};

class TreeArray {
public:
  int n;
  SegmentTree *a[MAXN+1];
  int lowbit(int k) {
    return k&(-k);
  }

  void add(int x, int y, int v) {
    for (int i=x; i<=n; i+=lowbit(i)) {
      if (!a[i]) {
	a[i] = new SegmentTree(1, n);
      }
      a[i]->add(y, v);
    }
  }

  int get(int x, int y) {
    int ret=0;
    for (int i=x; i>0; i-=lowbit(i)) {
      if (a[i]) {
	ret+=a[i]->get(y, n);
      }
    }
    return ret;
  }
};

class Oper {
public:
  int t, x, w;
};

void sort(Oper *a, int l, int r) {
  int i=l, j=r, mid=a[(l+r)/2].t;
  Oper temp;
  for (; i<=j; ) {
    for (; a[j].t>mid; j--);
    for (; a[i].t<mid; i++);
    if (i<=j) {
      temp=a[i], a[i]=a[j], a[j]=temp;
      i++, j--;
    }
  }
  if (i<r) {
    sort(a, i, r);
  }
  if (j>l) {
    sort(a, l, j);
  }
}

int main() {
  freopen("appletree.in", "r", stdin);
  freopen("appletree.out", "w", stdout);

  static Oper grow[MAXM+1], ques[MAXQ+1];
  static Graph g;
  int n, m, q;
  scanf("%d %d %d", &n, &m, &q);
  for (int i=1; i<=n; i++) {
    int a;
    scanf("%d", &a);
    ques[i].t=0, ques[i].x=i, ques[i].w=a;
  }
  for (int i=1; i<n; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    g.addSide(x, y);
    g.addSide(y, x);
  }

  g.build(1, 0);

  for (int i=1; i<=m; i++) {
    scanf("%d %d %d", &grow[i+n].t, &grow[i+n].x, &grow[i+n].w);
  }
  m+=n;
  sort(grow, 1, n);
  for (int i=1; i<=q; i++) {
    scanf("%d %d", &ques[i].t, &ques[i].x);
    ques[i].w = i;
  }
  sort(ques, 1, q);

  static TreeArray tree;
  static int ans[MAXQ+1];
  tree.n = n;
  for (int i=1, p=1; i<=q; i++) {
    for (; grow[p].t<ques[i].t && p<=m; p++) {
      tree.add(g.dfn[grow[p].x], g.dep[grow[p].x]+grow[p].t, grow[p].w);
    }
    ans[i] = tree.get(g.dfn[ques[i].x]+g.size[ques[i].x]-1, g.dep[ques[i].x]+ques[i].t)-tree.get(g.dfn[ques[i].x], g.dep[ques[i].x]+ques[i].t);
  }

  for (int i=1; i<=q; i++) {
    printf("%d\n", ans[i]);
  }

  fclose(stdin);
  fclose(stdout);
  return 0;
}
